﻿@page "/stockout"
@using Wms.Core.Entities
@using Microsoft.EntityFrameworkCore
@inject Wms.Data.WarehouseDbContext Db
@inject NavigationManager Navigation
@inject IJSRuntime JSRuntime

<div class="container-fluid py-4">
    <h3 class="text-primary mb-4">
        <span class="oi oi-data-transfer-up me-2"></span> 新增出库单
    </h3>

    <div class="card shadow-sm">
        <div class="card-body">
            <!-- 基本信息 -->
            <div class="row g-3 mb-4">
                <div class="col-md-6">
                    <label class="form-label">出库单号</label>
                    <input type="text" class="form-control" @bind="order.OrderNo" readonly />
                </div>
                <div class="col-md-6">
                    <label class="form-label">出库日期</label>
                    <input type="datetime-local" class="form-control" @bind="order.Date" />
                </div>
                <div class="col-md-6">
                    <label class="form-label">出库类型</label>
                    <select class="form-select" @bind="order.Type">
                        <option value="@StockOutType.Sales">销售出库</option>
                        <option value="@StockOutType.Production">生产领料</option>
                        <option value="@StockOutType.Other">其他出库</option>
                    </select>
                </div>
            </div>

            <!-- 明细操作 -->
            <button class="btn btn-outline-primary btn-sm mb-3" @onclick="AddRow">
                <span class="oi oi-plus"></span> 添加明细
            </button>

            @if (details.Any())
            {
                <table class="table table-bordered">
                    <thead class="table-light">
                        <tr>
                            <th>物料</th>
                            <th>数量</th>
                            <th>库位</th>
                            <th>可用库存</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        @for (int i = 0; i < details.Count; i++)
                        {
                            var d = details[i];
                            <tr>
                                <td>
                                    <InputSelect Value="@(d.ItemId)"
                                                 ValueExpression="@( () => d.ItemId )"
                                                 ValueChanged="@( async (int value) => await OnItemChanged(d, value) )"
                                                 class="form-control">
                                        <option value="0">请选择物料</option>
                                        @foreach (var item in allItems)
                                        {
                                            <option value="@item.Id">@item.Name (@item.Code)</option>
                                        }
                                    </InputSelect>
                                </td>
                                <td>
                                    <input type="number" class="form-control" min="1" @bind="d.Quantity" />
                                </td>
                                <td>
                                    <select class="form-select" @bind="d.LocationId">
                                        <option value="0">请选择库位</option>
                                        @if (d.ItemId > 0)
                                        {
                                            @foreach (var loc in d.AvailableLocations)
                                            {
                                                <option value="@loc.LocationId">
                                                    @loc.Code (库存: @loc.Quantity)
                                                </option>
                                            }
                                        }
                                    </select>
                                </td>
                                <td>
                                    <span>@d.AvailableQuantity</span>
                                </td>
                                <td>
                                    <button class="btn btn-sm btn-danger" @onclick="() => RemoveRow(d)">
                                        <span class="oi oi-trash"></span>
                                    </button>
                                </td>
                            </tr>
                        }
                    </tbody>
                </table>
            }
            else
            {
                <div class="alert alert-info">请添加至少一条出库明细。</div>
            }
        </div>
    </div>

    <!-- 操作按钮 -->
    <div class="mt-3">
        <button class="btn btn-success me-2" @onclick="SaveOrder" disabled="@(details.Count == 0)">
            保存出库单
        </button>
        <button class="btn btn-secondary" @onclick="Cancel">取消</button>
    </div>
</div>
@code {
    [Parameter] public int? Id { get; set; }
    private StockOutOrder order = new StockOutOrder
        {
            OrderNo = $"SO-{DateTime.Now:yyyyMMddHHmmss}",
            Date = DateTime.Now,
            Type = StockOutType.Other
        };
    private List<StockOutDetailDto> details = new();
    private List<Item> allItems = new();
    private List<Location> allLocations = new(); 
    private List<Wms.Core.Entities.Inventory> allInventories = new();

    public class StockOutDetailDto
    {
        public int ItemId { get; set; }
        public int LocationId { get; set; }
        public List<LocationStockDto> AvailableLocations { get; set; } = new();
        public int AvailableQuantity { get; set; }    
        public int Quantity { get; set; } = 1;
    }

    public class LocationStockDto
    {
        public int LocationId { get; set; }
        public string Code { get; set; } = "";
        public int Quantity { get; set; }
    }

    protected override async Task OnInitializedAsync()
    {
        allItems = await Db.Items.ToListAsync();
        allLocations = await Db.Locations.ToListAsync();
        allInventories = await Db.Inventories.ToListAsync(); // 全量库存
        Console.WriteLine("Loaded Inventories:");
        foreach (var inv in allInventories)
        {
            Console.WriteLine($"ItemId: {inv.ItemId}, LocationId: {inv.LocationId}, Quantity: {inv.Quantity}");
        }

        if (Id.HasValue)
        {
            // 编辑模式
            order = await Db.StockOutOrders
                .Include(o => o.Details)
                .FirstOrDefaultAsync(o => o.Id == Id.Value);

            if (order != null)
            {
                details = new List<StockOutDetailDto>();
                foreach (var d in order.Details)
                {
                    details.Add(new StockOutDetailDto
                        {
                            ItemId = d.ItemId,
                            LocationId = d.LocationId,
                            Quantity = d.Quantity,
                            AvailableQuantity = await GetAvailableStockAsync(d.ItemId, d.LocationId)
                        });
                }
            }
        }
        else
        {
            AddRow();
        }
    }

    private void AddRow()
    {
        details.Add(new StockOutDetailDto());
    }

    private void RemoveRow(StockOutDetailDto d)
    {
        details.Remove(d);
    }

    private async Task UpdateAvailableStock(StockOutDetailDto d)
    {
        if (d.ItemId <= 0 || d.LocationId <= 0)
        {
            d.AvailableQuantity = 0;
            return;
        }

        var inv = await Db.Inventories
            .FirstOrDefaultAsync(i => i.ItemId == d.ItemId && i.LocationId == d.LocationId);

        d.AvailableQuantity = inv?.Quantity ?? 0;
        Console.WriteLine($"[UpdateAvailableStock] ItemId={d.ItemId}, LocationId={d.LocationId}, Qty={d.AvailableQuantity}");

        await InvokeAsync(StateHasChanged);
    }

    private async Task<int> GetAvailableStockAsync(int itemId, int locationId)
    {
        var inventory = await Db.Inventories
            .FirstOrDefaultAsync(i => i.ItemId == itemId && i.LocationId == locationId);

        return inventory?.Quantity ?? 0;
    }

    private async Task OnItemChanged(StockOutDetailDto detail, int itemId)
    {
        detail.ItemId = itemId;

        if (itemId > 0)
        {
            var locStocks = await Db.Inventories
                .Include(i => i.Location)
                .Where(i => i.ItemId == itemId)
                .ToListAsync();

            var availableLocations = new List<LocationStockDto>();
            foreach (var i in locStocks)
            {
                var qty = await GetAvailableStockAsync(i.ItemId, i.LocationId);
                if (qty > 0)
                {
                    availableLocations.Add(new LocationStockDto
                        {
                            LocationId = i.LocationId,
                            Code = i.Location.Code,
                            Quantity = qty
                        });
                }
            }

            detail.AvailableLocations = availableLocations;
            detail.AvailableQuantity = availableLocations.Sum(x => x.Quantity);
        }
        else
        {
            detail.AvailableLocations.Clear();
            detail.AvailableQuantity = 0;
        }

        await InvokeAsync(StateHasChanged);
    }



    private async Task SaveOrder()
    {
        var validDetails = details
            .Where(d => d.ItemId > 0 && d.LocationId > 0 && d.Quantity > 0)
            .ToList();

        if (!validDetails.Any())
        {
            await JSRuntime.InvokeVoidAsync("alert", "请填写有效明细！");
            return;
        }

        using var tx = await Db.Database.BeginTransactionAsync();
        try
        {
            // 校验库存
            foreach (var d in validDetails)
            {
                var stock = await Db.Inventories
                    .Where(i => i.ItemId == d.ItemId && i.LocationId == d.LocationId)
                    .Select(i => i.Quantity)
                    .FirstOrDefaultAsync();

                if (d.Quantity > stock)
                {
                    await JSRuntime.InvokeVoidAsync("alert", $"物料 {d.ItemId} 库存不足！可用: {stock}");
                    await tx.RollbackAsync();
                    return;
                }
            }

            if (Id.HasValue)
            {
                var existingOrder = await Db.StockOutOrders.Include(o => o.Details)
                    .FirstOrDefaultAsync(o => o.Id == Id.Value);
                if (existingOrder != null)
                {
                    existingOrder.OrderNo = order.OrderNo;
                    existingOrder.Date = order.Date;
                    existingOrder.Type = order.Type;

                    Db.StockOutDetails.RemoveRange(existingOrder.Details);

                    existingOrder.Details = validDetails.Select(d => new Wms.Core.Entities.StockOutDetail
                        {
                            ItemId = d.ItemId,
                            LocationId = d.LocationId,
                            Quantity = d.Quantity
                        }).ToList();
                }
            }
            else
            {
                order.Details = validDetails.Select(d => new Wms.Core.Entities.StockOutDetail
                    {
                        ItemId = d.ItemId,
                        LocationId = d.LocationId,
                        Quantity = d.Quantity
                    }).ToList();

                Db.StockOutOrders.Add(order);
            }

            await Db.SaveChangesAsync();

            // 扣减库存
            foreach (var d in validDetails)
            {
                var inventory = await Db.Inventories
                    .FirstOrDefaultAsync(i => i.ItemId == d.ItemId && i.LocationId == d.LocationId);

                inventory.Quantity -= d.Quantity;
            }

            await Db.SaveChangesAsync();
            await tx.CommitAsync();

            Navigation.NavigateTo("/stockout-list");
        }
        catch
        {
            await tx.RollbackAsync();
            throw;
        }
    }


    private void Cancel()
    {
        Navigation.NavigateTo("/stockout-list");
    }
}